package com.bdqn.petmalldemo.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bdqn.petmalldemo.common.KetaiException;
import com.bdqn.petmalldemo.common.ResultCodeEnum;
import com.bdqn.petmalldemo.common.SystemConstants;
import com.bdqn.petmalldemo.entity.Follow;
import com.bdqn.petmalldemo.entity.Product;
import com.bdqn.petmalldemo.entity.User;
import com.bdqn.petmalldemo.mapper.FollowMapper;
import com.bdqn.petmalldemo.mapper.ProductMapper;
import com.bdqn.petmalldemo.mapper.UserMapper;
import com.bdqn.petmalldemo.service.FollowService;
import com.bdqn.petmalldemo.vo.FollowProductVO;
import com.bdqn.petmalldemo.vo.FollowUserVo;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author Lenovo
 * @since 2020-02-10
 */
@Service
public class FollowServiceImpl extends ServiceImpl<FollowMapper, Follow> implements FollowService {

    @Resource
    private UserMapper userMapper;
    @Resource
    private ProductMapper productMapper;
    @Resource
    private FollowMapper followMapper;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void addFollow(String userId, String productId) {
        Product product = productMapper.selectById(productId);
        //根据登录用户Id查询用户的基本信息
        User user = userMapper.selectById(userId);
        //如果当前登录用户与当前商品所属的卖家为同一个人,则不能收进行收藏
        if (userId.equals(product.getUserId())) {
            throw new KetaiException(ResultCodeEnum.PROHIBIT_COLLECTION_OF_OWN_GOODS);
        }
        //更新当前用户的收藏数量
        user.setFollowNum(user.getFollowNum()+1);
        userMapper.updateById(user);

        //针对商品添加收藏数量

        product.setFollowNum(product.getFollowNum()+1);
        productMapper.updateById(product);

        //生成收藏记录
        Follow follow = new Follow();
        follow.setProductId(productId)
                .setUserId(userId)
                .setSellerId(product.getUserId());
        baseMapper.insert(follow);

        //更新当前商品卖家的粉丝数量,如果同一用户收藏了同一卖家的不同商品,只能算一个粉丝

        //根据卖家的Id找到所售全部商品信息
        QueryWrapper<Product> productQueryWrapper = new QueryWrapper<>();
        productQueryWrapper.eq("user_id",product.getUserId());
        List<Product> productListBySellerId = productMapper.selectList(productQueryWrapper);
        //通过Stream提取出当前集合中的商品Id
        List<String> productIdList = productListBySellerId.stream().map(Product::getId).collect(Collectors.toList());
        //获取当前用户所有的收藏商品Id
        QueryWrapper<Follow> followQueryWrapper = new QueryWrapper<>();
        followQueryWrapper.eq("user_id",userId);
        List<String> followProductIdList = baseMapper.selectList(followQueryWrapper).stream()
                .map(Follow::getProductId).collect(Collectors.toList());

        if (!CollectionUtils.isEmpty(productIdList)&&!CollectionUtils.isEmpty(followProductIdList)) {
            //比对当前两者是否存在交集,或者说是followProductIdList是否为productList的子集
            productIdList.retainAll(followProductIdList);//只是执行取交集的子集(用多的去执行少的)
            if (!CollectionUtils.isEmpty(followProductIdList)) {
                //如果当前用户已经收藏的商品Id的集合不是当前卖家所售的商品Id的子集,
                // 就证明当前用户是第一次收藏该卖家的商品,需要新一个粉丝
                User seller = userMapper.selectById(product.getUserId());
                seller.setFansNum(seller.getFansNum()+1);
                userMapper.updateById(seller);
            }
        }

    }

    @Override
    public boolean checkExist(String userId, String productId) {
        QueryWrapper<Follow> followQueryWrapper = new QueryWrapper<>();
        followQueryWrapper.eq("user_id",userId)
                .eq("product_id",productId);
        Integer count = baseMapper.selectCount(followQueryWrapper);
        //如果存在,直接抛出一个自定义异常,提示已经被收藏
        if (count>0) {
          return true;
        }
        return false;
    }

    @Override
    public Map<String,Object> getFollowProduct(String userId, Integer currentPage) {
        //处理查询条件,当前页的起始数据的下标,譬如第一页小标为0,如果每页记录数为10条.第二页的小标为10
        Integer startIndex= StringUtils.isEmpty(currentPage)||Integer.valueOf(0).equals(currentPage)?0:
                (currentPage - 1)* SystemConstants.PAGE_SIZE;
        //根据查询条件及分页条件执行分页查询
        List<FollowProductVO> followProductVOList = followMapper.selectFollowProductByUserId(userId,startIndex,SystemConstants.PAGE_SIZE);
        //查询总记录数
        Integer total=followMapper.countFollowProductByUserId(userId);
        //计算totalPage,总页数,(总记录数)/每页记录数
        Integer totalPage=total%SystemConstants.PAGE_SIZE==0 ? total/SystemConstants.PAGE_SIZE:
                (total/SystemConstants.PAGE_SIZE)+1;
        Map<String,Object> map =new HashMap<>(16);
        map.put("list",followProductVOList);
        map.put("pages",totalPage);
        map.put("total",total);
        map.put("pageNum",currentPage);
        return map;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void removeFollowById(Long followId) {
        //先根据收藏记录Id查询
        Follow follow = baseMapper.selectById(followId);
        //删除收藏记录
        baseMapper.deleteById(followId);
        //修改当前用户的收藏数量
        User user = userMapper.selectById(follow.getUserId());
        user.setFollowNum(user.getFollowNum()-1);
        userMapper.updateById(user);
        //修改当前商品的被收藏数量
        Product product = productMapper.selectById(follow.getProductId());
        product.setFollowNum(product.getFollowNum()-1);
        productMapper.updateById(product);

        //处理被收藏商品的卖家的粉丝数据
        QueryWrapper<Product> productQueryWrapper = new QueryWrapper<>();
        productQueryWrapper.eq("user_id",product.getUserId());
        //获取当前商品所属的用户所出售的所有商品
        List<Product> productList = productMapper.selectList(productQueryWrapper);
        List<String> productIdList = productList.stream().map(Product::getId).collect(Collectors.toList());
        //获取当前用户的收藏商品Id
        QueryWrapper<Follow> followQueryWrapper = new QueryWrapper<>();
        followQueryWrapper.eq("user_id",user.getId());
        List<String> followProductIdList = baseMapper.selectList(followQueryWrapper)
                .stream().map(Follow::getProductId).collect(Collectors.toList());
        //将两者进行比较处理
        followProductIdList.retainAll(productIdList);
        //如果为空,则证明是最后一条收藏记录,可取消粉丝
        if (!CollectionUtils.isEmpty(productIdList)) {
            User seller = userMapper.selectById(product.getUserId());
            seller.setFansNum(seller.getFansNum()-1);
            userMapper.updateById(seller);
        }

    }

    @Override
    public Map<String,Object> getFollowUserBySellerId(String sellerId,Integer currentPage) {
        //1.先根据登录用户获取获取所售商品信息
        QueryWrapper<Product> productQueryWrapper = new QueryWrapper<>();
        productQueryWrapper.eq("user_id", sellerId);
        List<Product> productList = productMapper.selectList(productQueryWrapper);
        if (CollectionUtils.isEmpty(productList)) {
            return new HashMap<>();
        }

        //2.根据所售商品获取收藏记录
        List<String> productIds = productList.stream().map(Product::getId).collect(Collectors.toList());
        QueryWrapper<Follow> followQueryWrapper = new QueryWrapper<>();
        //动态拼接查询条件
        followQueryWrapper.in("product_id", productIds);
        List<Follow> followList = baseMapper.selectList(followQueryWrapper);

        //3.根据收藏记录中的用户ID获取相关用户的信息
        //3.1、将收藏记录列表转换成为用户Id列表并且去重
        List<String> fansIds = followList.stream().map(Follow::getUserId).distinct().collect(Collectors.toList());
        if (CollectionUtils.isEmpty(fansIds)) {
            return new HashMap<>(16);
        }
        //3.2、封装分页对象,指定当前页和每页记录大小
        IPage<User> page = new Page<>(StringUtils.isEmpty(currentPage) ? 0 : currentPage, SystemConstants.PAGE_SIZE);
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.in("id", fansIds);
        userMapper.selectPage(page, userQueryWrapper);
        List<User> fansList = page.getRecords();
        List<FollowUserVo> followUserVoList = new ArrayList<>(fansList.size());
        //3.3、进行数据处理,将查询的用户记录封装成前端支持的数据结构
        fansList.forEach(user -> {
            FollowUserVo followUserVo = new FollowUserVo();
            //将密码置空
            user.setPassword("");
            followUserVo.setUser(user);
            followUserVo.setUserId(user.getId());
            followUserVoList.add(followUserVo);
        });
        Map<String, Object> map = new HashMap<>(16);
        //根据前端所需要的数据结构进行相应的处理
        map.put("list", followUserVoList);
        map.put("pages", page.getPages());
        map.put("total", page.getTotal());
        map.put("pageNum", currentPage);
        return map;
    }
}
